﻿// 泛型 类型在书写时不确定 可以指代任何类型 包括自定义类型 相当于一个占位符
// 虽然可以指代任何类型 但也不是毫无限制 我们可以给它一个约束
// 让它只能时某一类类型 格式 where T : 限定
// 每个where是单独一行 不用,隔开
// struct 值类型
// class 引用类型
// new() 必须具有公共的无参构造函数 多重约束它必须写在最后
// 基类 必须继承自该类
// 接口 必须继承该接口
// 多重约束,隔开 不能冲突

// 泛型方法 在方法名后加上 <自定义类型名> 多个用逗号,隔开
// 方法内部就可以使用这个自定义类型名来代替类型
// 在方法被调用时 会自动识别这个类型是什么类型

// 泛型类 在类名后加上<自定义类型名> 多个用,隔开 (接口其实就是一个特殊的类)
// 必须在声明时就确定类型具体是什么类型 且之后无法修改

// 泛型委托 同上
// 需要绑定静态？

// 值类型 使用时其实用的是复制的 不会影响源数据
// 引用类型 使用的就是源数据 修改会影响源数据
// 装箱和拆箱
// 装箱就是将值类型转换为引用类型
// 拆箱就是将引用类型转换为值类型
// C#中所有的数据类型都有一个共同的(最终的)基类 object
// 值类型与引用类型相互转换就是通过object作为桥梁的
// 类型转换比较消耗性能 所以我们应该尽量避免类型转换 泛型可以有效避免过度类型转换

// 数据结构
// 链式 树状
// 链式 不分叉
// 树状 分叉
// 特殊的链式结构
// Stack 堆栈 先进后出 Push(在最后端添加数据) Pop(拿出最后段的数据)
// Queue 队列 先进先出 Enqueue(在最后段段加数据) Dequeue(拿出最前端的数据)

// 因为存储方式不同 数组需要存在一块连续的内存空间上
// 所以数组的扩容非常麻烦 每次都要申请新的内存空间 然后一个个复制
// 查找非常方便

// 链式结构添加和删除元素非常方便 查找非常麻烦

using _11_Generic;

internal class Program
{
    static event Action action;

    private static void Main(string[] args)
    {
        // 闭包
        // 匿名函数(Lambda表达式)所用到的外部变量会形成一个闭包
        // 闭包中的变量就不再是原来的生命周期了 以便应对不知何时的调用

        //for (int i = 0; i < 3; i++)
        //{
        //    action = () => Console.WriteLine(i);
        //}

        //action.Invoke();


        BSTree tree = new BSTree();
        tree.Insert(4);
        tree.Insert(2);
        tree.Insert(6);
        tree.Insert(1);
        tree.Insert(7);
        tree.Insert(5);
        tree.Insert(3);
        tree.Insert(8);

        tree.Remove(6);
        tree.Print();





        return;



        Test t = new Test();

        t.One().Two().Three();

        MyList<string> myList = new MyList<string>();
        Node<string> node1 = new Node<string>("node1");
        Node<string> node2 = new Node<string>("node2");
        Node<string> node3 = new Node<string>("node3");
        Node<string> node4 = new Node<string>("node4");
        Node<string> node5 = new Node<string>("node5");

        var node = myList.Add(node1);
        myList.Add(node2);
        myList.Add(node3);
        myList.Add(node4);
        myList.Add(node5);

        myList.Insert(new Node<string>("插入"),node);

        //myList.Remove(2);
        //myList.Insert(2,"9");

        // $ 一般用于插入变量
        // @ 一般用于路径 防止转义
        // """ 保留换行信息

        myList.Print();

        Stack<int> list;
        list.Pop();

        // 链式调用
    }


    class Test
    {
        public Test One()
        {
            Console.WriteLine(1);
            return this;
        } 
        public Test Two()
        {
            Console.WriteLine(2);
            return this;
        }
        public Test Three()
        {
            Console.WriteLine(3);
            return this;
        }
    }
}

